{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Quantum State Tomography (Unsupervised Learning)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Quantum state tomography (QST) is a machine learning task which aims to reconstruct the full quantum state from measurement results.\n",
    "\n",
    "__Aim__: Given a variational ansatz $\\Psi(\\lbrace \\boldsymbol{\\beta} \\rbrace)$ and a set of measurement results, we want to find the parameters $\\boldsymbol{\\beta}$ which best reproduce the probability distribution of the measurements.\n",
    "\n",
    "__Training Data__: A set of single shot measurements in some basis, e.g. $\\lbrace(100010, \\textrm{XZZZYZ}), (011001, \\textrm{ZXXYZZ}), \\dots \\rbrace$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import netket as nk\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import math \n",
    "import sys"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "While in practice, the measurement results can be experimental data e.g. from a quantum computer/simulator, for our purpose, we shall construct our data set by making single shot measurement on a wavefunction that we have obtained via exact diagonalisation. For this tutorial, we shall focus on the one-dimensional anti-ferromagnetic transverse-field Ising model defined by\n",
    "\n",
    "$$H = \\sum_{i} Z_{i}Z_{i+1} + h \\sum_{i} X_{i}$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define the Hamiltonian\n",
    "N = 8\n",
    "g = nk.graph.Hypercube(length=N, n_dim=1, pbc=False)\n",
    "hi = nk.hilbert.Spin(g, s=0.5)\n",
    "ha = nk.operator.Ising(hi, h=1.0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, perform exact diagonalisation to obtain the ground state wavefunction."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Ground state energy = -9.837951447459439\n"
     ]
    }
   ],
   "source": [
    "# Obtain the ED wavefunction\n",
    "res = nk.exact.lanczos_ed(ha, first_n=1, compute_eigenvectors=True)\n",
    "psi = res.eigenvectors[0]\n",
    "print(\"Ground state energy =\", res.eigenvalues[0])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, to construct the dataset, we will make single shot measurements in various bases. To obtain a single shot measurement, we need to sample from the wavefunction in the relevant basis.\n",
    "\n",
    "Since the wavefunction we obtained is in the computational basis (i.e. $Z$ basis), to obtain a single shot measurement in another basis, one would need to transform the wavefunction as follows (this is similar to how one would do a measurement in a different basis on a quantum computer):\n",
    "\n",
    "X Basis:\n",
    "$$ |{\\Psi}\\rangle \\rightarrow I_n \\otimes \\frac{1}{\\sqrt{2}}\\pmatrix{1 & 1 \\\\ 1& -1} \\otimes I_m \\ |\\Psi\\rangle$$\n",
    "\n",
    "Y Basis:\n",
    "$$ |{\\Psi}\\rangle \\rightarrow I_n \\otimes \\frac{1}{\\sqrt{2}}\\pmatrix{1 & -i \\\\ 1& i} \\otimes I_m \\ |\\Psi\\rangle$$ "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def build_rotation(hi, basis):\n",
    "    localop = nk.operator.LocalOperator(hi, 1.0)\n",
    "    U_X = 1.0 / (math.sqrt(2)) * np.asarray([[1.0, 1.0], [1.0, -1.0]])\n",
    "    U_Y = 1.0 / (math.sqrt(2)) * np.asarray([[1.0, -1j], [1.0, 1j]])\n",
    "\n",
    "    N = hi.size\n",
    "\n",
    "    assert len(basis) == hi.size\n",
    "\n",
    "    for j in range(hi.size):\n",
    "        if basis[j] == \"X\":\n",
    "            localop *= nk.operator.LocalOperator(hi, U_X, [j])\n",
    "        if basis[j] == \"Y\":\n",
    "            localop *= nk.operator.LocalOperator(hi, U_Y, [j])  \n",
    "    return localop"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Number of bases: 16\n",
      "Number of shots: 1000\n",
      "Total size of the dataset: 16000\n",
      "Some single shot results: (sample, basis)\n",
      " [(array([ 1.,  1.,  1., -1.,  1., -1.,  1., -1.]), 0), (array([ 1.,  1., -1.,  1., -1.,  1., -1.,  1.]), 0), (array([-1.,  1., -1.,  1., -1.,  1., -1.,  1.]), 0)]\n"
     ]
    }
   ],
   "source": [
    "n_basis = 2*N\n",
    "n_shots = 1000\n",
    "\n",
    "\n",
    "rotations = []\n",
    "training_samples = []\n",
    "training_bases = []\n",
    "\n",
    "np.random.seed(1234)\n",
    "\n",
    "for m in range(n_basis):\n",
    "    basis = np.random.choice(\n",
    "        list(\"XYZ\"), size=N, p=[1.0 / N, 1.0 / N, (N - 2.0) / N]\n",
    "    )\n",
    "    \n",
    "    psi_rotated = np.copy(psi)\n",
    "    if 'X' in basis or 'Y' in basis:\n",
    "        rotation = build_rotation(hi, basis)\n",
    "        psi_rotated = rotation.to_sparse().dot(psi_rotated)\n",
    "    psi_square = np.square(np.absolute(psi_rotated))\n",
    "    \n",
    "    rand_n = np.random.choice(hi.n_states, p=psi_square, size=n_shots)\n",
    "\n",
    "    for rn in rand_n:\n",
    "        training_samples.append(hi.number_to_state(rn))\n",
    "    training_bases += [m] * n_shots\n",
    "\n",
    "    rotations.append(rotation)\n",
    "\n",
    "print('Number of bases:', n_basis)\n",
    "print('Number of shots:', n_shots)\n",
    "print('Total size of the dataset:', n_basis*n_shots)\n",
    "print('Some single shot results: (sample, basis)\\n', list(zip(training_samples[:3], training_bases[:3])))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The basis rotations are contained in ``rotations`` and the single shot measurements are stored in ``training_samples``.  ``training_bases`` is a list of integers which labels each samples in ``training_samples`` according to their basis."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Having obtained the dataset, we can proceed to define the variational ansatz one wishes to train. We shall simply use the Restricted Boltzmann Machine (RBM) with real parameters defined as:\n",
    "\n",
    "$$ \\tilde\\psi (\\boldsymbol{\\sigma})  =  p_{\\boldsymbol{\\lambda}}(\\boldsymbol{\\sigma}) e^{i \\phi_{\\boldsymbol{\\mu}}(\\boldsymbol{\\sigma})} $$\n",
    "\n",
    "where $\\phi_{\\boldsymbol{\\mu}}(\\boldsymbol{\\sigma}) = \\log  p_{\\boldsymbol{\\mu}}(\\boldsymbol{\\sigma})$ and $p_{\\boldsymbol{\\lambda/\\mu}}$ are standard RBM real probability distributions. Notice that the amplitude part $p_{\\boldsymbol{\\lambda}}$ completely defines the measurements in the Z basis and vice versa.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define the variational wavefunction ansatz\n",
    "ma = nk.machine.RbmSpinPhase(hilbert=hi, alpha=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With the variational ansatz as well as the dataset, the quantum state tomography can now be performed. Recall that the aim is to reconstruct a wavefunction $|\\Psi_{U}\\rangle$ (for our case, the ground state of the 1D TFIM) given single shot measurements of the wavefunction in various bases. The single shot measurements are governed by a probability distribution \n",
    "\n",
    "$$P_{b}(\\boldsymbol{\\sigma}) = | \\langle \\boldsymbol{\\sigma}| \\hat{U}_{b} |\\Psi_{U}\\rangle|^{2}$$ \n",
    "\n",
    "which depends on $|\\Psi_{U}\\rangle$ and the basis $b$ in which the measurement is performed. $\\hat{U}_{b}$ is simply the unitary which rotates the wavefunction into the corresponding basis.\n",
    "\n",
    "Similarly, the variational wavefunction $|\\tilde\\psi\\rangle$ also defines a set of basis dependent probability distributions $\\tilde P_{b}(\\boldsymbol{\\sigma})$. The optimisation procedure is then basically a minimisation task to find the set of parameters $\\boldsymbol{\\kappa}$ which minimises the total Kullback–Leibler divergence between $\\tilde P_{b}$ and $P_{b}$, i.e.\n",
    "\n",
    "$$ \\Xi(\\boldsymbol{\\kappa}) = \\sum_{b} \\mathbb{KL}_{b}({\\kappa}) $$\n",
    "\n",
    "where \n",
    "\n",
    "$$\\mathbb{KL}_{b}({\\boldsymbol{\\kappa}}) = \\sum_{\\boldsymbol{\\sigma}} P_{b}(\\boldsymbol{\\sigma}) \\log \\frac{ P_{b}(\\boldsymbol{\\sigma})}{\\tilde P_{b}(\\boldsymbol{\\sigma})}$$.\n",
    "\n",
    "This minimisation can be achieved by gradient descent. Although one does not have access to the underlying probability distributions $P_{b}(\\boldsymbol{\\sigma})$, the total KL divergence can be estimated by summing over the dataset $\\lbrace D_{b} \\rbrace$\n",
    "\n",
    "$$ \\Xi(\\boldsymbol{\\kappa}) = -\\sum_{b} \\sum_{\\boldsymbol{\\sigma} \\in D_{b}} \\log \\tilde P_{b}(\\boldsymbol{\\sigma}) + S $$\n",
    "\n",
    "where $S$ is the constant entropy of $P_{b}(\\boldsymbol{\\sigma})$ which can be ignored. The details regarding the computation of the gradients can be found in arXiv:1703.05334."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In addition to reconstructing the quantum state, we would also like to investigate how the size of the dataset affects the quality of the reconstruction. To that end, we shall run the optimisation with different dataset sizes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Shuffle our datasets\n",
    "import random\n",
    "temp = list(zip(training_bases, training_samples))\n",
    "random.shuffle(temp)\n",
    "training_bases, training_samples = zip(*temp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Sampler\n",
    "sa = nk.sampler.MetropolisLocal(machine=ma)\n",
    "\n",
    "# Optimizer\n",
    "op = nk.optimizer.AdaDelta()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Starting optimisation for dataset size 2000\n",
      "Starting optimisation for dataset size 4000\n",
      "Starting optimisation for dataset size 8000\n",
      "Starting optimisation for dataset size 16000\n"
     ]
    }
   ],
   "source": [
    "dataset_sizes = [2000, 4000, 8000, 16000]\n",
    "# During the optimisation, we would like to keep track \n",
    "# of the fidelities and energies\n",
    "fidelities = {} \n",
    "energies = {}\n",
    "\n",
    "for size in dataset_sizes:\n",
    "    # First remember to reinitialise the machine\n",
    "    ma.init_random_parameters(seed=1234, sigma=0.01)\n",
    "    # Quantum State Tomography object\n",
    "    qst = nk.unsupervised.Qsr(\n",
    "        sampler=sa,\n",
    "        optimizer=op,\n",
    "        batch_size=300,\n",
    "        n_samples=300,\n",
    "        rotations=tuple(rotations[:size]),\n",
    "        samples=training_samples[:size],\n",
    "        bases=training_bases,\n",
    "        method=\"Gd\"\n",
    "    )\n",
    "    qst.add_observable(ha, \"Energy\")\n",
    "    \n",
    "    # Run the optimisation using the iterator\n",
    "    print(\"Starting optimisation for dataset size\", size)\n",
    "    fidelities_temp = []\n",
    "    energies_temp = []\n",
    "    for step in qst.iter(2000, 100):\n",
    "        # Compute fidelity with exact state\n",
    "        psima = ma.to_array()\n",
    "        fidelity = np.abs(np.vdot(psima, psi))\n",
    "        fidelities_temp.append(fidelity)\n",
    "    fidelities[size] = fidelities_temp\n",
    "    energies[size] = energies_temp"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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4aGN6Js58/S//UOHDvHHP/6RiooKzGYzU6dObfY9Wjpv7NixzJs3j1tvvZWbbtJaoFevXs2BAwdYunQpoP3iP378OEajscUYhw8fzn333YfNZuNXv/pVkwRxym9/+1smTpzIjBkz+P7770lNTWXs2LEAWK3WZn+dP/300zz99NOt/ZnOUlBQwN13383ixYvR6S6PGQYdliCklHYhxGPAKkAPfCylPCyEeAXYK6VMBMYDrwshJFoT06MdFc+FKK+xkl1Wy51DQsn9zW+Rdjvf3z8IH47Sy68XbH0H3EwQNrirQ1WULjdv3jyWLVtGQkICixYtYuPGje0677333mPXrl2sWLGCoUOHkpSUhJSSt99+u0myaem9Aa655ho2b97MihUrmDdvHk8++SRz5569/e+iRYvIysrinXe0kfRSSiZPnswXX3xxzu/4xhtv8NlnnzX7mW+99VaT41VVVVx//fW89tprjBo1CoCAgAAqKiqw2+0YDAZyc3MJD9e6acPDw8nJySEiIgK73U5lZSUBAQGNx0858zUdoUPTmJRypZSyl5QyVkr5WsOxFxqSA1LKpVLKng3nPCCltDTzHouklI91ZJytObWC68jvF1F/6BChf36NHx0HGBM2RhvymrkVoseCTu2vpFwZrrnmGpYtW0ZdXR3V1dUsX768say6uppu3bphs9nOuoh6e3tTXV3d6nnp6emMHDmSV155haCgIHJycpg6dSr//ve/sdlsABw7doyampom73mmrKwsQkJCmD9/Pg888AD79u07qzwpKYk333yT//znP42/6EeNGsW2bdtIS0sDoKamhmPHjjV576effprk5OQmt+aSg9Vq5cYbb2Tu3LncfPPNjceFEEyYMKGxVrR48WJmzdIGcs6cOZPFixcDsHTpUiZOnIgQgpkzZ7JkyRIsFgsnTpzg+PHjjBgxotnvfzF0dSf1ZSElp5Ip2btx3ZdIwPz5ZA0OpWplFWPDx0JlHpRlwPD5XR2monSaIUOGMGfOHBISEggODmb48OGNZa+++iojR44kKCiIkSNHNl7Ab7vtNubPn89bb73F0qVLWzzv6aef5vjx40gpmTRpEgkJCcTHx5OZmcmQIUOQUhIUFMSyZcuIj49Hr9eTkJDAvHnzzuqH2LhxI2+88QYuLi54eXnxySefnPUd3nnnHcrKypgwYQIAw4YN48MP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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "for size in fidelities:\n",
    "    plt.plot(np.arange(1,21,1),fidelities[size], label='dataset size = '+str(size))\n",
    "plt.axhline(y=1, xmin=0,\n",
    "            xmax=20, linewidth=3, color='k', label='Perfect Fidelity')\n",
    "plt.ylabel('Fidelity')\n",
    "plt.xlabel('Iteration')\n",
    "plt.xticks(range(0,21,4))\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As expected, it is relatively clear that with increasing dataset size, the final fidelity does increase."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "netket",
   "language": "python",
   "name": "netket"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
